using System;
using System.IO;
using System.Text;

using Microsoft.SPOT;

using GHIElectronics.NETMF.Hardware;

using Skewworks.Pyxis.GUI.Controls;

namespace Skewworks.Pyxis.Kernel
{
    internal static class settings
    {

        #region Variables

        private static PyxisAPI API;
        private static bool bLoaded = false;
        private static menuitem AppMenu = null;
        private static form frmMain = null;
        private static menuitem mnuQuitApp;
        private static menuitem mnuSwitchToApp;
        private static Bitmap buffer2 = null;

        #endregion

        #region Public Methods

        public static void ShowSettings(PyxisAPI api)
        {

            if (!bLoaded)
            {
                API = api;
                ShowDialog("Loading Settings; Please Wait...");
                CreateApp();
                bLoaded = true;
                API.ScreenBuffer.DrawImage(0, 0, buffer2, 0, 0, buffer2.Width, buffer2.Height);
            }

            // Update menus
            if (API.desktop._mnu.count > 1) API.desktop._mnu.remove(1);
            API.desktop._mnu.add(AppMenu);

            // Display App
            API.ActiveForm = frmMain;

        }

        public static void QuitSettings()
        {
            if (!bLoaded) return;

            API.desktop.mnuRun.RemoveItem(mnuSwitchToApp);
            API.desktop.mnuForce.RemoveItem(mnuQuitApp);
            if (API.desktop.mnuForce.ItemCount == 0) API.desktop.mnuForce.enabled = false;
            if (API.desktop.mnuRun.ItemCount == 0) API.desktop.mnuRun.enabled = false;

            API.DisplayDesktop();

            frmMain = null;
            mnuQuitApp = null;
            mnuSwitchToApp = null;

            bLoaded = false;
        }

        #endregion

        #region Private Methods

        private static void BrowseWallpaper(textbox txtWall)
        {
            string sVal = API.OpenFile("Select Wallpaper", API.MyDrives.RootDirectory + "\\pyxis\\wallpapers\\", new string[] { ".jpg", ".jpe", ".jpeg", ".bmp", ".gif" });
            if (sVal != string.Empty) txtWall.text = sVal;
        }

        private static void CreateApp()
        {
            // Create Menus
            AppMenu = new menuitem("Settings");
            //menuitem mnuRestore = new menuitem("Restore Defaults");
            //AppMenu.AddItem(mnuRestore);
            //AppMenu.AddItem(new menuitem("-"));
            menuitem mnuExit = new menuitem("Quit");
            mnuExit.tapEvent += new MenuItemTap((object sender) => QuitSettings());
            AppMenu.AddItem(mnuExit);

            // Create Switch/Quit Menus
            mnuSwitchToApp = new menuitem("Settings");
            mnuSwitchToApp.tapEvent += new MenuItemTap((object sender) => ShowSettings(API));
            mnuSwitchToApp.Tag = "Settings";
            API.desktop.mnuRun.AddItem(mnuSwitchToApp);
            API.desktop.mnuRun.enabled = true;

            mnuQuitApp = new menuitem("Settings");
            mnuQuitApp.tapEvent += new MenuItemTap((object sender) => QuitSettings());
            mnuQuitApp.Tag = "Settings";
            API.desktop.mnuForce.AddItem(mnuQuitApp);
            API.desktop.mnuForce.enabled = true;

            // Create Form
            frmMain = new form(API, Colors.LightGray, true, true);
            tabdialog TD = new tabdialog(4, 4, frmMain.width - 8, frmMain.height - 37);

            tab tAppearance = new tab("Appearance");

            textbox txtWall = new textbox("", 4, 24, frmMain.width - 95, 20);
            tAppearance.addChild(txtWall);

            button btnBrowse = new button("Browse", frmMain.width - 87, 22);
            btnBrowse.tapEvent += new OnTap((object sender, point e) => BrowseWallpaper(txtWall));
            tAppearance.addChild(btnBrowse);

            if (API.MyDrives.RootDirectory == "\\")
            {
                tAppearance.addChild(new label("Wallpaper: (Cannot be set without a primary drive)", 4, 6));
                btnBrowse.enabled = false;
                txtWall.text = "[System Default]";
                txtWall.enabled = false;
            }
            else
            {
                // Read system settings
                XMLReaderEX xr = new XMLReaderEX(API.MyDrives.RootDirectory + "\\pyxis\\system\\desktop.xml");
                XMLNodeEX node = (XMLNodeEX)xr.Nodes[0];
                node = node.NodeByName("Appearance");
                string sPaper = node.NodeByName("Wallpaper").Value;
                if (sPaper.IndexOf("\\") < 0) sPaper = API.MyDrives.RootDirectory + "\\pyxis\\wallpapers\\" + sPaper;
                txtWall.text = sPaper;
                tAppearance.addChild(new label("Wallpaper:", 4, 6));
            }

            TD.AddTab(tAppearance);

            tab tNetwork = new tab("Network");

            tNetwork.addChild(new label("IP Address:", 24, 30));
            textbox txtIP = new textbox(API.MyNetwork.EthernetIPAddress, 94, 28, 100, 20);
            txtIP.enabled = false;
            tNetwork.addChild(txtIP);

            tNetwork.addChild(new label("Gateway:", 24, 54));
            textbox txtGateway = new textbox(API.MyNetwork.EthernetGatewayAddress, 94, 52, 100, 20);
            txtGateway.enabled = false;
            tNetwork.addChild(txtGateway);

            tNetwork.addChild(new label("Subnet Mask:", 24, 78));
            textbox txtSubnet = new textbox(API.MyNetwork.EthernetSubnetMask, 94, 76, 100, 20);
            txtSubnet.enabled = false;
            tNetwork.addChild(txtSubnet);

            tNetwork.addChild(new label("Connection:", 4, 6));
            combobox cboNet = new combobox(65, 4, 70, 20, new string[] { "None", "DHCP", "Static IP" });
            cboNet.SelectedIndexChanged += new OnSelectedIndexChange((object sender, int value) => ConnectionTypeChanged(cboNet, txtIP, txtGateway, txtSubnet));
            cboNet.SelectedIndex = (int)SettingsManager.BootSettings.ConnectionType;
            tNetwork.addChild(cboNet);

            checkbox chkUpdates = new checkbox(4, 134);
            chkUpdates.value = SettingsManager.BootSettings.CheckUpdates;
            tNetwork.addChild(chkUpdates);
            tNetwork.addChild(new label("Check for updates at start-up", 24, 135));

            TD.AddTab(tNetwork);

            tab tDate = new tab("Date/Time");

            checkbox chkRTC = new checkbox(4, 4);
            if (API.ActiveDevice == PyxisAPI.DeviceType.ChipworkX)
            {
                chkRTC.value = true;
                chkRTC.enabled = false;
            }
            else
            {
                chkRTC.value = SettingsManager.BootSettings.EnableRTC;
            }
            tDate.addChild(chkRTC);
            tDate.addChild(new label("Enable Real-Time Clock", 24, 5));

            combobox cboMonth = new combobox(24, 28, 90, 20, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "Septemper", "October", "November", "December" });
            cboMonth.SelectedIndex = DateTime.Now.Month - 1;
            cboMonth.enabled = chkRTC.value;
            tDate.addChild(cboMonth);

            numericupdown numDay = new numericupdown(116, 28, 35, 1, 31, DateTime.Now.Day);
            numDay.enabled = chkRTC.value;
            tDate.addChild(numDay);

            numericupdown numYear = new numericupdown(154, 28, 54, 2010, 2210, DateTime.Now.Year);
            numYear.enabled = chkRTC.value;
            tDate.addChild(numYear);

            numericupdown numHour = new numericupdown(24, 52, 35, 1, 12, (DateTime.Now.Hour > 12) ? DateTime.Now.Hour - 12 : DateTime.Now.Hour);
            numHour.enabled = chkRTC.value;
            tDate.addChild(numHour);
            tDate.addChild(new label(":", 62, 53));
            numericupdown numMin = new numericupdown(67, 52, 35, 0, 59, DateTime.Now.Minute);
            numMin.enabled = chkRTC.value;
            numMin.forceZeros = true;
            tDate.addChild(numMin);
            tDate.addChild(new label(":", 105, 53));
            numericupdown numSec = new numericupdown(110, 52, 35, 0, 59, DateTime.Now.Second);
            numSec.enabled = chkRTC.value;
            numSec.forceZeros = true;
            tDate.addChild(numSec);
            combobox cboAP = new combobox(148, 52, 40, 20, new string[] { "AM", "PM" });
            cboAP.enabled = chkRTC.value;
            cboAP.SelectedIndex = (DateTime.Now.Hour > 12) ? 1 : 0;
            tDate.addChild(cboAP);

            chkRTC.tapEvent += new OnTap((object sender, point e) => RTCChanged(chkRTC, cboMonth, numDay, numYear, numHour, numMin, numSec, cboAP));
            TD.AddTab(tDate);

            tab tSound = new tab("Sounds");
            tSound.addChild(new label("Volume:", 4, 6));
            numericupdown numVol = new numericupdown(45, 4, 36, 0, 100, SettingsManager.BootSettings.Volume);
            tSound.addChild(numVol);

            tSound.addChild(new label("Bass", Colors.Black, FontManager.Tahoma11Bold, 4, 30, 30, 20, true, true));
            tSound.addChild(new label("Amplitude:", 24, 47));
            combobox cboBAmp = new combobox(80, 45, 60, 20, new string[] { "0.0dB", "1.5dB", "3.0dB", "4.5dB", "6.0dB", "7.5dB", "9.0dB", "10.5dB", "12.0dB", "13.5dB", "15.0dB", "16.5dB", "18.0dB", "19.5dB", "21.0dB", "22.5dB" });
            tSound.addChild(cboBAmp);
            tSound.addChild(new label("FQ Limit:", 24, 71));
            combobox cboBFq = new combobox(80, 69, 60, 20, new string[] { "0Hz", "10Hz", "20Hz", "30Hz", "40Hz", "50Hz", "60Hz", "70Hz", "80Hz", "90Hz", "100Hz", "110Hz", "120Hz", "130Hz", "140Hz", "150Hz" });
            tSound.addChild(cboBFq);


            tSound.addChild(new label("Treble", Colors.Black, FontManager.Tahoma11Bold, 154, 30, 36, 20, true, true));
            tSound.addChild(new label("Amplitude:", 174, 47));
            combobox cboTAmp = new combobox(230, 45, 60, 20, new string[] { "0.0dB", "1.0dB", "2.0dB", "3.0dB", "4.0dB", "5.0dB", "6.0dB", "7.0dB", "8.0dB", "9.0dB", "10.0dB", "11.0dB", "12.0dB", "13.0dB", "14.0dB", "15.0dB" });
            tSound.addChild(cboTAmp);
            tSound.addChild(new label("FQ Limit:", 174, 71));
            combobox cboTFq = new combobox(230, 69, 60, 20, new string[] { "0KHz", "1KHz", "2KHz", "3KHz", "4KHz", "5KHz", "6KHz", "7KHz", "8KHz", "9KHz", "10KHz", "11KHz", "12KHz", "13KHz", "14KHz", "15KHz" });
            tSound.addChild(cboTFq);

            TD.AddTab(tSound);

            if (API.ActiveDevice != PyxisAPI.DeviceType.ChipworkX)
                tSound.enabled = false;

            button btnCancel = new button("Cancel", frmMain.width - 79, frmMain.height - 29);
            btnCancel.tapEvent += new OnTap((object sender, point e) => QuitSettings());
            frmMain.AddChild(btnCancel);

            button btnOK = new button("Save", frmMain.width - 158, frmMain.height - 29);
            btnOK.tapEvent += new OnTap((object sender, point e) => SaveSettings(txtWall, cboNet, txtIP, txtGateway, txtSubnet, chkRTC, cboMonth, numDay, numYear, numHour, numMin, numSec, cboAP, numVol, cboBAmp, cboBFq, cboTAmp, cboTFq, chkUpdates));
            frmMain.AddChild(btnOK);

            frmMain.AddChild(TD);
        }

        private static void ConnectionTypeChanged(combobox cboNet, textbox txtIP, textbox txtGateway, textbox txtSubnet)
        {
            if (cboNet.SelectedIndex == 2)
            {
                txtIP.enabled = true;
                txtGateway.enabled = true;
                txtSubnet.enabled = true;
            }
            else
            {
                txtIP.enabled = false;
                txtIP.text = API.MyNetwork.EthernetIPAddress;
                txtGateway.enabled = false;
                txtGateway.text = API.MyNetwork.EthernetGatewayAddress;
                txtSubnet.enabled = false;
                txtSubnet.text = API.MyNetwork.EthernetSubnetMask;
            }
        }

        private static void RTCChanged(checkbox chkRTC, combobox cboMonth, numericupdown numDay, numericupdown numYear, numericupdown numHour, numericupdown numMin, numericupdown numSec, combobox cboAP)
        {
            cboMonth.enabled = chkRTC.value;
            numHour.enabled = chkRTC.value;
            numMin.enabled = chkRTC.value;
            numSec.enabled = chkRTC.value;
            cboAP.enabled = chkRTC.value;
            numDay.enabled = chkRTC.value;
            numYear.enabled = chkRTC.value;
        }

        private static void SaveSettings(textbox txtWall, combobox cboNet, textbox txtIP, textbox txtGateway, textbox txtSubnet, checkbox chkRTC, combobox cboMonth, numericupdown numDay, numericupdown numYear, numericupdown numHour, numericupdown numMin, numericupdown numSec, combobox cboAP, numericupdown numVol, combobox cboBAmp, combobox cboBFq, combobox cboTAmp, combobox cboTFq, checkbox chkUpdates)
        {
            ShowDialog("Saving Settings; Please Wait...");

            // Appearance
            if (txtWall.enabled)
            {
                byte[] b = File.ReadAllBytes(API.MyDrives.RootDirectory + "\\pyxis\\system\\desktop.xml");
                string sXML = new string(Encoding.UTF8.GetChars(b));
                int i = sXML.IndexOf("<Wallpaper");
                int e = sXML.IndexOf("</Wallpaper");
                b = Encoding.UTF8.GetBytes( sXML.Substring(0, i + 11) + txtWall.text + sXML.Substring(e));
                FileStream iFile = new FileStream(API.MyDrives.RootDirectory + "\\pyxis\\system\\desktop.xml", FileMode.OpenOrCreate, FileAccess.Write);
                iFile.Write(b, 0, b.Length);
                iFile.Close();

                API.desktop._bkgImage = PyxisAPI.ImageFromBytes(File.ReadAllBytes(txtWall.text));
            }

            // Network, Date/Time and Sounds
            SettingsManager.SaveBootSettings((NetworkConnectionType)cboNet.SelectedIndex, txtIP.text, txtGateway.text, txtSubnet.text, chkUpdates.value, chkRTC.value, (byte)numVol.value, (byte)cboTAmp.SelectedIndex, (byte)cboTFq.SelectedIndex, (byte)cboBAmp.SelectedIndex, (byte)cboBFq.SelectedIndex);

            if (API.MyNetwork.AutoConnect != (NetworkConnectionType)cboNet.SelectedIndex)
            {
                API.MyNetwork.AutoConnect = (NetworkConnectionType)cboNet.SelectedIndex;
                if (cboNet.SelectedIndex == 2)
                {
                    API.MyNetwork.SetStaticIP(txtIP.text, txtSubnet.text, txtGateway.text);
                }
            }

            if (chkRTC.value)
            {
                RealTimeClock.SetTime(new DateTime(numYear.value, cboMonth.SelectedIndex + 1, numDay.value, numHour.value,numMin.value,numSec.value));
            }

            QuitSettings();
        }

        private static void ShowDialog(string Message)
        {
            int w, h, x, y, i;

            // Copy out the current buffer
            buffer2 = new Bitmap(AppearanceManager.ScreenWidth, AppearanceManager.ScreenHeight);
            buffer2.DrawImage(0, 0, API._buffer, 0, 0, buffer2.Width, buffer2.Height);

            // First figure out how wide to make the window
            FontManager.Tahoma11.ComputeExtent(PyxisAPI.Product, out w, out h);
            size sz = FontManager.ComputeExtentEx(FontManager.Tahoma11, Message);
            if (sz.width > w) w = sz.width;

            // Add border
            w += 16;

            // Check Mimimum Width
            if (w < 76) w = 76;

            // Now make sure we're within the screen width
            if (w > AppearanceManager.ScreenWidth - 8) w = AppearanceManager.ScreenWidth - 8;

            // Get the height of the 2 strings combined
            // We already have the title height in h
            // Remove 16px for 2 borders + 2 spacers (4+4+4+4)
            FontManager.Tahoma11.ComputeTextInRect(Message, out y, out i, w - 16);
            h = h + i;

            // Add borders and spacing 49px (4 border + 2 space + title + 2 space + 4 border = 4 space + text height + 4 space + button height + 4 space + 4 border)
            h = h + 20;

            // Make sure we're still on the screen
            if (h > AppearanceManager.ScreenHeight - 8) h = AppearanceManager.ScreenHeight - 8;

            // Center the window
            x = (int)(((float)AppearanceManager.ScreenWidth / 2) - ((float)w / 2));
            y = (int)(((float)AppearanceManager.ScreenHeight / 2) - ((float)h / 2));

            // We're ready to create the window
            form frmLaunch = new form(API, Colors.LightGray, x, y, w, h, true, true, form.WindowType.fullborder);
            frmLaunch.AddChild(new label(PyxisAPI.Product, Colors.White, 6, 5, w - 10, FontManager.Tahoma11.Height));
            frmLaunch.AddChild(new label(Message, Colors.Black, 8, 5 + FontManager.Tahoma11.Height + 6, w - 16, h - 20 - FontManager.Tahoma11.Height));

            // Set the Active Form (without rendering)
            API._ActiveForm = frmLaunch;

            // Draw Prompt
            API._buffer.DrawRectangle(Colors.Black, 0, 0, 0, buffer2.Width, buffer2.Height, 0, 0, Colors.Black, 0, 0, Colors.Black, 0, 0, 100);
            API._buffer.Flush();
            frmLaunch.Render();
        }

        #endregion

    }
}
